﻿// This code is released under the BSD license.
namespace PugLib.Threading
{
    using System;

    /// <summary>
    /// 
    /// </summary>
    public static class AsyncWrapper
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="f"></param>
        /// <param name="callback"></param>
        public static void DoAsync<TResult>(Func<TResult> f, Action<TResult> callback)
        {
            f.BeginInvoke(x => callback(f.EndInvoke(x)), null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="f"></param>
        /// <param name="arg"></param>
        /// <param name="callback"></param>
        public static void DoAsyncWithArgument<TInput, TResult>(Func<TInput, TResult> f, TInput arg,
                                                                Action<TResult> callback)
        {
            f.BeginInvoke(arg, x => callback(f.EndInvoke(x)), null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="f"></param>
        /// <param name="arg"></param>
        /// <param name="callback"></param>
        public static void DoAsync<TInput, TResult>(this Func<TInput, TResult> f, TInput arg, Action<TResult> callback)
        {
            f.BeginInvoke(arg, x => callback(f.EndInvoke(x)), null);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TResult"></typeparam>
        /// <param name="f"></param>
        /// <param name="arg"></param>
        /// <param name="callback"></param>
        public static void DoAsyncStatic<TInput, TResult>(Func<TInput, TResult> f, TInput arg, Action<TResult> callback)
        {
            f.BeginInvoke(arg, x => callback(f.EndInvoke(x)), null);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="argument"></param>
        /// <param name="actionFunction"></param>
        public static void RunInBackground<T>(T argument, Action<T> actionFunction)
        {
            ThreadPoolHelper.QueueUserWorkItem(argument, actionFunction);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="argument"></param>
        /// <param name="actionFunction"></param>
        public static void RunInBackground<TIn, TOut>(TIn argument, Func<TIn, TOut> actionFunction)
        {
            ThreadPoolHelper.QueueUserWorkItem(argument, actionFunction);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TIn"></typeparam>
        /// <typeparam name="TOut"></typeparam>
        /// <param name="argument"></param>
        /// <param name="actionFunction"></param>
        public static void TransformInBackground<TIn, TOut>(TIn argument, Func<TIn, TOut> actionFunction)
        {
            ThreadPoolHelper.QueueUserWorkItem(argument, actionFunction);
        }
    }
}